#include <iostream>

#include "../../include/component_module.h"
#include "../../include/loader.h"
#include "../../include/mutex.h"
#include "../../tests/test1/test_impl.h"
#include "../../include/ref_obj_qi_ptr.h"

BOSS_MODULE_INIT(Boss::Mutex);

class MyReceiver
  : public Boss::CoClassBase
    <
      Boss::TL::TypeListAdapter
        <
          Test::IWriter,
          Test::IReceiverImpl
        >
    >
{
public:
  // IWriter
  virtual void BOSS_CALL_TYPE Write(const char *str)
  {
    Boss::ISyncObject Lock(GetSynObj());
    if (!str)
      return;
    std::cout << str << std::endl;
  }

protected:
  ~MyReceiver()
  {
  }
  virtual void ProcessMsg(Test::IMessage *msg)
  {
    Boss::RefObjPtr<Test::IMessage> Msg(msg);
    if (!Msg.Get())
      return;
    Boss::ISyncObject Lock(GetSynObj());
    std::cout << Msg->Get() << std::endl;
  }
};

int main()
{
  try
  {
    Boss::Loader Loader("./", "./Reg.reg");
    Loader.RegModule("./" BOSS_SERVICE_MODULE_PREF "test_component1" BOSS_SERVICE_MODULE_EXT);
    Loader.RegModule("./" BOSS_SERVICE_MODULE_PREF "test_component2" BOSS_SERVICE_MODULE_EXT);
    Boss::RefObjPtr<Test::ITestService> TestSrv = Loader.CreateObject<Test::ITestService>(TEST_ITESTMSGMGRSERVICEIMPL);
    if (TestSrv->Start() != Boss::rcOk)
    {
      std::cerr << "Can't start test service" << std::endl;
      return 0;
    }
    Boss::RefObjQIPtr<Test::IMessageMgr> MsgMgr(TestSrv);
    if (!MsgMgr.Get())
    {
      std::cerr << "Interface IMessageMgr not found" << std::endl;
      TestSrv->Stop();
      return 0;
    }
    Loader.GetSysServiceLocator()->AddService(BOSS_UUID_OF(Test::IMessageMgr), MsgMgr.Get());
    Boss::RefObjPtr<Test::IReceiver> Receiver = Boss::IBaseImpl<MyReceiver>::Create();
    MsgMgr->Subscribe(Receiver.Get());
    Loader.GetSysServiceLocator()->AddService(BOSS_UUID_OF(Test::IWriter), Receiver.Get());
    Boss::RefObjPtr<Test::ITestService> TestRecvSrv = Loader.CreateObject<Test::ITestService>(TEST_ITESTRECVSERVICEIMPL);
    if (TestRecvSrv->Start() != Boss::rcOk)
    {
      std::cerr << "Can't start recv test service" << std::endl;
      TestRecvSrv->Stop();
      Loader.GetSysServiceLocator()->DelService(BOSS_UUID_OF(Test::IMessageMgr));
      TestSrv->Stop();
      return 0;
    }
    std::cin.get();
    TestRecvSrv->Stop();
    Loader.GetSysServiceLocator()->DelService(BOSS_UUID_OF(Test::IMessageMgr));
    TestSrv->Stop();
  }
  catch (std::exception &e)
  {
    std::cerr << e.what() << std::endl;
  }
  return 0;
}
